package customer

import (
	"context"
	"errors"
	dto "git.mycaigou.com/gfyx/micro-gfyx-mp-api/infrastructure/dto/business_opportunity"
	customer2 "git.mycaigou.com/gfyx/micro-gfyx-mp-api/infrastructure/repository/business_opportunity"
	pb "git.mycaigou.com/gfyx/micro-gfyx-mp-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/business_opportunity"
	"git.mycaigou.com/gfyx/micro-gfyx-mp-api/service/business_opportunity/bid"
	"git.mycaigou.com/gfyx/micro-gfyx-mp-api/service/business_opportunity/project"

	"git.myscrm.cn/golang/stark/v4"
)

type customerService struct {
	customerRepo    customer2.CustomerRepositoryIface
	bidService      bid.BidServiceIface
	projectService  project.ProjectServiceIface
	buildingService project.BuildingServiceIface
}

// NewCustomerService 找客户
func NewCustomerService(
	customerRepo customer2.CustomerRepositoryIface,
	bidService bid.BidServiceIface,
	projectService project.ProjectServiceIface,
	buildingService project.BuildingServiceIface,
) CustomerServiceIface {
	return &customerService{
		customerRepo:    customerRepo,
		bidService:      bidService,
		projectService:  projectService,
		buildingService: buildingService,
	}
}

// 获取备选项
func (s *customerService) GetAllOptions(ctx context.Context, params []string) (interface{}, error) {
	return s.customerRepo.GetAllOptions(ctx, params)
}

// 获得开发商动态
func (s *customerService) GetFeeds(ctx context.Context, params map[string]interface{}) (interface{}, error) {
	return s.customerRepo.GetFeeds(ctx, params)
}

// 拿地列表
func (s *customerService) TakeLand(ctx context.Context, params map[string]interface{}) (interface{}, error) {
	return s.customerRepo.TakeLand(ctx, params)
}

// 开盘列表
func (s *customerService) OpenedTrading(ctx context.Context, params map[string]interface{}) (interface{}, error) {
	return s.customerRepo.OpenedTrading(ctx, params)
}

// 公司下拉选项
func (s *customerService) CompanyOption(ctx context.Context, params map[string]interface{}) (interface{}, error) {
	return s.customerRepo.CompanyOption(ctx, params)
}

// 校验开发商是否在主档案
func (s *customerService) CheckDeveloperMainData(ctx context.Context, params map[string]interface{}) (interface{}, error) {
	return s.customerRepo.CheckDeveloperMainData(ctx, params)
}

// 申请反哺开发商主档案接口
func (s *customerService) ApplyDeveloperMainData(ctx context.Context, params map[string]interface{}) (interface{}, error) {
	return s.customerRepo.ApplyDeveloperMainData(ctx, params)
}

// GetDeveloperScoreDetail 获取好客户得分
func (s *customerService) GetDeveloperScoreDetail(ctx context.Context, organizingCode string) (*dto.CustomerScore, error) {
	return s.customerRepo.GetDeveloperScoreDetail(ctx, organizingCode)
}

func (s *customerService) GetSupplierProject(ctx context.Context, request *dto.SupplierProjectRequest) (*dto.SupplierProjectResponse, error) {
	requestPb := &pb.GetSupplierProjectRequest{
		OrganizingCode: request.OrganizingCode,
		Keyword:        request.Keyword,
		AreaCode:       request.AreaCode,
		CoopTimeMax:    request.CoopTimeMax,
		CoopTimeMin:    request.CoopTimeMin,
		Page:           request.Page,
		PageSize:       request.PageSize,
	}
	resPb, err := s.customerRepo.GetSupplierProject(ctx, requestPb)
	res := &dto.SupplierProjectResponse{
		List: []*dto.SupplierProjectItem{},
	}
	if err != nil {
		stark.Logger.Error(ctx, "GetSupplierProject，失败:", err)
		return res, err
	}

	res.Total = resPb.Total
	for _, item := range resPb.List {
		supplierProjectItem := &dto.SupplierProjectItem{
			Id:                item.Id,
			CoopAmount:        item.CoopAmount,
			CoopAmountOrgin:   item.CoopAmountOrgin,
			CoopCity:          item.CoopCity,
			CoopCityCode:      item.CoopCityCode,
			OrganizingCode:    item.OrganizingCode,
			CoopCompanyCode:   item.CoopCompanyCode,
			CoopCompanyName:   item.CoopCompanyName,
			CoopEndTime:       item.CoopEndTime,
			CoopStartTime:     item.CoopStartTime,
			CoopPrjName:       item.CoopPrjName,
			CoopProjectType:   item.CoopProjectType,
			CoopProvince:      item.CoopProvince,
			CoopProvinceCode:  item.CoopProvinceCode,
			DataSource:        item.DataSource,
			SupplierId:        item.SupplierId,
			SupplierName:      item.SupplierName,
			SubSupplierName:   item.SubSupplierName,
			SubOrganizingCode: item.SubOrganizingCode,
		}
		res.List = append(res.List, supplierProjectItem)
	}
	return res, nil
}

func (s *customerService) GetBiddingList(ctx context.Context, request *dto.GetBiddingListRequest) (*dto.SearchBidResponse, error) {
	searchBidRequest := &dto.SearchBidRequest{
		Page:             request.Page,
		PageSize:         request.PageSize,
		Keyword:          request.Keyword,
		SearchType:       make([]string, 0),
		AreaCode:         request.AreaCode,
		PublishDateStart: request.PublishDateStart,
		PublishDateEnd:   request.PublishDateEnd,
		OrganizingCode:   request.OrganizingCode,
		Type:             request.Type,
	}
	//与找招中标列表逻辑一致。
	resp, err := s.bidService.SearchBid(ctx, searchBidRequest, 2)
	if err != nil {
		stark.Logger.Errorf(ctx, "获取招标列表异常,err:%s", err.Error())
	}
	return resp, nil
}

// GetProjectLifeCycle 项目合并列表
func (s *customerService) GetProjectLifeCycle(ctx context.Context, request *dto.GetProjectLifeCycleRequest) (*dto.SearchProjectResponse, error) {
	searchBidRequest := &dto.SearchProjectRequest{
		Page:               request.Page,
		PageSize:           request.PageSize,
		Keyword:            request.Keyword,
		OrganizingCode:     request.OrganizingCode,
		AreaCode:           request.AreaCode,
		ProjectType:        request.ProjectType,
		FitmentFee:         request.FitmentFee,
		LandUsage:          request.LandUsage,
		TakeLandDateStart:  request.TakeLandDateStart,
		TakeLandDateEnd:    request.TakeLandDateEnd,
		ProjectDateStart:   request.ProjectDateStart,
		ProjectDateEnd:     request.ProjectDateEnd,
		BuildingDateStart:  request.BuildingDateStart,
		BuildingDateEnd:    request.BuildingDateEnd,
		OpenDateStart:      request.OpenDateStart,
		OpenDateEnd:        request.OpenDateEnd,
		CompletedDateStart: request.CompletedDateStart,
		CompletedDateEnd:   request.CompletedDateEnd,
	}
	//与找项目合并列表逻辑一致。
	resp, err := s.projectService.SearchProject(ctx, searchBidRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "获取找项目列表异常,err:%s", err.Error())
	}
	return resp, nil
}

func (s *customerService) GetFeedList(ctx context.Context, request *dto.GetFeedListRequest) (*dto.GetFeedListResponse, error) {
	requestPb := &pb.GetFeedRequest{
		OrganizingCode: request.OrganizingCode,
		Page:           1,
		PageSize:       10,
	}
	resPb, err := s.customerRepo.GetFeedList(ctx, requestPb)
	if err != nil {
		stark.Logger.Error(ctx, "GetFeedList，失败:", err)
		return nil, err
	}
	res := &dto.GetFeedListResponse{
		List: []*dto.GetFeedItem{},
	}
	res.Total = resPb.Total
	for _, item := range resPb.List {
		feedItem := &dto.GetFeedItem{
			OrganizingCode:        item.OrganizingCode,
			DeveloperName:         item.DeveloperName,
			FeedId:                item.FeedId,
			FeedTime:              item.FeedTime,
			FeedTitle:             item.FeedTitle,
			FeedType:              item.FeedType,
			RelatedDeveloperName:  item.RelatedDeveloperName,
			RelatedOrganizingCode: item.RelatedOrganizingCode,
		}
		res.List = append(res.List, feedItem)
	}
	return res, nil
}

func (s *customerService) GetInvestCompany(ctx context.Context, request *dto.GetInvestCompanyRequest) (*dto.GetInvestCompanyResponse, error) {
	requestPb := &pb.GetInvestCompanyRequest{
		OrganizingCode: request.OrganizingCode,
	}
	resPb, err := s.customerRepo.GetInvestCompany(ctx, requestPb)
	if err != nil {
		stark.Logger.Error(ctx, "GetInvestCompany，失败:", err)
		return nil, err
	}
	res := &dto.GetInvestCompanyResponse{
		List: []*dto.InvestCompanyItem{},
	}
	for _, item := range resPb.List {
		feedItem := &dto.InvestCompanyItem{
			OrganizingCode:       item.OrganizingCode,
			CompanyName:          item.CompanyName,
			ParentOrganizingCode: item.ParentOrganizingCode,
			Percent:              item.Percent,
		}
		res.List = append(res.List, feedItem)
	}
	return res, nil
}

func (s *customerService) SearchCustomerList(ctx context.Context, request *dto.GetCustomerListRequest) (*dto.GetCustomerListResponse, error) {
	resp := &dto.GetCustomerListResponse{
		MaxNum: 2000,
		Total:  0,
		List:   []*dto.CustomerItem{},
	}

	requestPb := &pb.SearchCustomerListRequest{
		Keyword:          request.Keyword,
		CompanyIdentity:  request.CompanyIdentity,
		AreaCodes:        request.AreaCodes,
		CompanyLevel:     request.CompanyLevel,
		CompanyLabel:     request.CompanyLabel,
		CompanyType:      request.CompanyType,
		IndustryCategory: request.IndustryCategory,
		LandUsageLabel:   request.LandUsageLabel,
		ProjectTypeLabel: request.ProjectTypeLabel,
		FitmentFeeLabel:  request.FitmentFeeLabel,
		BiddingArea:      request.BiddingArea,
		CreditLevel:      request.CreditLevel,
		Page:             request.Page,
		PageSize:         request.PageSize,
	}
	customerData, err := s.customerRepo.SearchCustomerList(ctx, requestPb)
	if err != nil {
		return nil, err
	}
	if customerData == nil {
		return resp, nil
	}

	resp.Total = customerData.Total
	for _, item := range customerData.List {
		resp.List = append(resp.List, formatCustomerDetailPb2DtoItem(item))
	}
	return resp, nil
}

func (s *customerService) GetCustomerDetail(ctx context.Context, request *dto.GetCustomerDetailRequest) (*dto.CustomerDetail, error) {
	detailResp, err := s.customerRepo.GetCustomerDetail(ctx, &pb.GetCustomerDetailRequest{
		OrganizingCode: request.OrganizingCode,
	})
	if err != nil {
		return nil, err
	}

	if detailResp == nil || detailResp.Detail == nil {
		return nil, errors.New("客户详情不存在")
	}
	detail := detailResp.Detail

	result := &dto.CustomerDetail{
		CustomerItem:             formatCustomerDetailPb2DtoItem(detail),
		Telephone:                detail.Telephone,
		BidCnt1Year:              detail.BidCnt_1Year,
		TakeLandCnt1Year:         detail.TakeLandCnt_1Year,
		CommencePermitCnt1Year:   detail.CommencePermitCnt_1Year,
		SellProjectCnt1Year:      detail.SellProjectCnt_1Year,
		CooperationCaseCnt1Year:  detail.CooperationCaseCnt_1Year,
		Scope:                    detail.Scope,
		CompanyProfile:           detail.CompanyProfile,
		EnterpriseNature:         detail.EnterpriseNature,
		TermStart:                detail.TermStart,
		TermEnd:                  detail.TermEnd,
		RecCapi:                  detail.RecCapi,
		NumberOfEmployees:        detail.NumberOfEmployees,
		Address:                  detail.Address,
		BidNum:                   detail.BidNum,
		ProjectNum:               detail.ProjectNum,
		TakeLandNum:              detail.TakeLandNum,
		CommencePermitNum:        detail.CommencePermitNum,
		SellProjectNum:           detail.SellProjectNum,
		CooperationEnterpriseNum: detail.CooperationEnterpriseNum,
		CooperationProjectNum:    detail.CooperationProjectNum,
	}
	return result, nil
}

func formatCustomerDetailPb2DtoItem(detail *pb.CustomerDetail) *dto.CustomerItem {
	if detail == nil {
		return nil
	}
	customerDtoItem := &dto.CustomerItem{
		CompanyName:              detail.CompanyName,
		CompanyNameHl:            detail.CompanyNameHl,
		OldCompanyNameHl:         detail.OldCompanyNameHl,
		OrganizingCode:           detail.OrganizingCode,
		CompanyLogo:              detail.CompanyLogo,
		BusinessStatusLabel:      detail.BusinessStatusLabel,
		TopCompanyName:           detail.TopCompanyName,
		TopCompanyOrganizingCode: detail.TopCompanyOrganizingCode,
		CompanyIdentity:          detail.CompanyIdentity,
		CompanyType:              detail.CompanyType,
		Province:                 detail.Province,
		City:                     detail.City,
		ProvinceCode:             detail.ProvinceCode,
		CityCode:                 detail.CityCode,
		LegalName:                detail.LegalName,
		RegistCapi:               detail.RegistCapi,
		EstablishDate:            detail.EstablishDate,
		IndustryCategory:         detail.IndustryCategory,
		BidCnt2Year:              detail.BidCnt_2Year,
		TakeLandCnt2Year:         detail.TakeLandCnt_2Year,
		CommencePermitCnt2Year:   detail.CommencePermitCnt_2Year,
		SellProjectCnt2Year:      detail.SellProjectCnt_2Year,
		CooperationCaseCnt2Year:  detail.CooperationCaseCnt_2Year,
		ContactNum:               detail.ContactNum,
		CustomerDynamic:          nil,
		IsExistCustomer:          detail.IsExistCustomer,
		OpptyStatus:              detail.OpptyStatus,
		EsScore:                  detail.EsScore,
		CreditLevel:              detail.CreditLevel,
		ProjectNameHl:            detail.ProjectNameHl,
	}
	if len(detail.CompanyLevel) != 0 {
		for _, level := range detail.CompanyLevel {
			customerDtoItem.CompanyLevel = append(customerDtoItem.CompanyLevel, dto.CustomerLabel{
				Label:  level.Label,
				Remark: level.Remark,
			})
		}
	} else {
		customerDtoItem.CompanyLevel = []dto.CustomerLabel{}
	}

	if len(detail.CompanyLabel) != 0 {
		for _, level := range detail.CompanyLabel {
			customerDtoItem.CompanyLabel = append(customerDtoItem.CompanyLabel, dto.CustomerLabel{
				Label:  level.Label,
				Remark: level.Remark,
			})
		}
	} else {
		customerDtoItem.CompanyLabel = []dto.CustomerLabel{}
	}
	if detail.CustomerDynamic != nil && detail.CustomerDynamic.TypeName != "" {
		customerDtoItem.CustomerDynamic = &dto.CustomerDynamicItem{
			TypeName: detail.CustomerDynamic.TypeName,
			Date:     detail.CustomerDynamic.Date,
			Title:    detail.CustomerDynamic.Title,
		}
	}
	return customerDtoItem
}

func (s *customerService) FuzzySearch(ctx context.Context, request *dto.FuzzySearchRequest) ([]*dto.FuzzySearchItem, error) {
	searchData, err := s.customerRepo.FuzzySearch(ctx, &pb.FuzzySearchCustomerRequest{Keyword: request.Keyword})
	if err != nil {
		return nil, err
	}
	var result []*dto.FuzzySearchItem
	if searchData == nil {
		return result, nil
	}

	for _, item := range searchData.List {
		result = append(result, &dto.FuzzySearchItem{
			CompanyName:      item.CompanyName,
			CompanyNameHl:    item.CompanyNameHl,
			OldCompanyNameHl: item.OldCompanyNameHl,
		})
	}
	return result, nil
}

// GetCustomerZxList 企业风险 - 失信被执行
func (s *customerService) GetCustomerZxList(ctx context.Context, request *dto.GetCustomerRiskCommonRequest) (*dto.GetCustomerZxListResponse, error) {
	zxListData, err := s.customerRepo.GetCustomerZxList(ctx, &pb.GetCustomerRiskCommonRequest{
		Keyword:       request.OrganizingCode,
		PageNum:       request.Page,
		PageSize:      request.PageSize,
		IsReturnTotal: 1,
	})
	if err != nil {
		return nil, err
	}
	resp := &dto.GetCustomerZxListResponse{
		Total: 0,
		List:  []*dto.CustomerZxListItem{},
	}
	if zxListData != nil {
		resp.Total = zxListData.Total
		for _, item := range zxListData.List {
			resp.List = append(resp.List, &dto.CustomerZxListItem{
				CaseDate:   item.CaseDate,
				CaseNo:     item.CaseNo,
				ExecuteGov: item.ExecuteGov,
				Biaodi:     item.Biaodi,
			})
		}
	}
	return resp, nil
}

// GetCustomerCourtRegister 企业风险 - 立案信息
func (s *customerService) GetCustomerCourtRegister(ctx context.Context, request *dto.GetCustomerRiskCommonRequest) (*dto.GetCustomerCourtRegisterResponse, error) {
	courtRegisterData, err := s.customerRepo.GetCustomerCourtRegister(ctx, &pb.GetCustomerRiskCommonRequest{
		Keyword:       request.OrganizingCode,
		PageNum:       request.Page,
		PageSize:      request.PageSize,
		IsReturnTotal: 1,
	})
	if err != nil {
		return nil, err
	}
	resp := &dto.GetCustomerCourtRegisterResponse{
		Total: 0,
		List:  []*dto.CustomerCourtRegister{},
	}
	if courtRegisterData != nil {
		resp.Total = courtRegisterData.Total
		for _, item := range courtRegisterData.List {
			resp.List = append(resp.List, &dto.CustomerCourtRegister{
				Litigant:    item.Litigant,
				Plaintiff:   item.Plaintiff,
				Defendant:   item.Defendant,
				CompanyName: item.CompanyName,
				CaseType:    item.CaseType,
				CaseStatus:  item.CaseStatus,
				CaseNo:      item.CaseNo,
				Court:       item.Court,
				FilingDate:  item.FilingDate,
				CaseReason:  item.CaseReason,
			})
		}
	}
	return resp, nil
}

// GetCustomerLawSuit 企业风险 - 法律诉讼
func (s *customerService) GetCustomerLawSuit(ctx context.Context, request *dto.GetCustomerRiskCommonRequest) (*dto.GetCustomerLawSuitResponse, error) {
	lawSuitData, err := s.customerRepo.GetCustomerLawSuit(ctx, &pb.GetCustomerRiskCommonRequest{
		Keyword:       request.OrganizingCode,
		PageNum:       request.Page,
		PageSize:      request.PageSize,
		IsReturnTotal: 1,
	})
	if err != nil {
		return nil, err
	}
	resp := &dto.GetCustomerLawSuitResponse{
		Total: 0,
		List:  []*dto.CustomerLawSuit{},
	}
	if lawSuitData != nil {
		resp.Total = lawSuitData.Total
		for _, item := range lawSuitData.List {
			resp.List = append(resp.List, &dto.CustomerLawSuit{
				Title:        item.Title,
				CompanyName:  item.CompanyName,
				LawsuitUrl:   item.LawsuitUrl,
				LawsuitH5Url: item.LawsuitH5Url,
				Court:        item.Court,
				DocType:      item.DocType,
				CaseType:     item.CaseType,
				SubmitTime:   item.SubmitTime,
				JudgeTime:    item.JudgeTime,
				CaseReason:   item.CaseReason,
			})
		}
	}
	return resp, nil
}

// GetCustomerTaxIllegal 企业风险 - 税收违法
func (s *customerService) GetCustomerTaxIllegal(ctx context.Context, request *dto.GetCustomerRiskCommonRequest) (*dto.GetCustomerTaxIllegalResponse, error) {
	taxIllegalData, err := s.customerRepo.GetCustomerTaxIllegal(ctx, &pb.GetCustomerRiskCommonRequest{
		Keyword:       request.OrganizingCode,
		PageNum:       request.Page,
		PageSize:      request.PageSize,
		IsReturnTotal: 1,
	})
	if err != nil {
		return nil, err
	}
	resp := &dto.GetCustomerTaxIllegalResponse{
		Total: 0,
		List:  []*dto.CustomerTaxIllegal{},
	}
	if taxIllegalData != nil {
		resp.Total = taxIllegalData.Total
		for _, item := range taxIllegalData.List {
			resp.List = append(resp.List, &dto.CustomerTaxIllegal{
				OperName:          item.OperName,
				CompanyName:       item.CompanyName,
				OrganizingCode:    item.OrganizingCode,
				Address:           item.Address,
				CaseNature:        item.CaseNature,
				IllegalContent:    item.IllegalContent,
				IllegalTime:       item.IllegalTime,
				AgencyCompanyName: item.AgencyCompanyName,
			})
		}
	}
	return resp, nil
}

// GetCustomerRiskCount 企业风险-数量统计
func (s *customerService) GetCustomerRiskCount(ctx context.Context, request *dto.GetCustomerRiskCountRequest) (*dto.GetCustomerRiskCountResponse, error) {
	data, err := s.customerRepo.GetCustomerRiskCount(ctx, &pb.GetCustomerRiskCountRequest{
		Keyword: request.OrganizingCode,
	})
	if err != nil {
		return nil, err
	}
	resp := &dto.GetCustomerRiskCountResponse{}
	if data != nil {
		resp = &dto.GetCustomerRiskCountResponse{
			ZxListCount:        data.ZxListCount,
			CourtRegisterCount: data.CourtRegisterCount,
			LawSuitCount:       data.LawSuitCount,
			TaxIllegalCount:    data.TaxIllegalCount,
			RiskTotalCount:     data.ZxListCount + data.CourtRegisterCount + data.LawSuitCount + data.TaxIllegalCount,
		}
	}
	return resp, nil
}
